package com.zrs.gmall.cart.service.impl;

import com.zrs.gmall.cart.model.CartInfo;
import com.zrs.gmall.cart.service.CartService;
import com.zrs.gmall.common.constant.RedisConst;
import com.zrs.gmall.common.util.DateUtil;
import com.zrs.gmall.product.client.ProductFeignClient;
import com.zrs.gmall.product.model.SkuInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private ProductFeignClient productFeignClient;

    /**
     * 将商品加入购物车
     *
     * @param userId
     * @param skuId
     * @param skuNum
     */
    @Override
    public void addToCart(String userId, Long skuId, Integer skuNum) {
        //1 构建用户的购物车hash结构Key  形式:user:用户ID:cart
        String redisKey = getCartKey(userId);

        //2 判断当前商品ID是否在Hash接口中,如果存在-对购物数量累加;如果不存在构建新CarInfo对象存入Redis
        //2.1 创建操作某个用户购物车hash结构操作对象
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(redisKey);
        //2.2 判断商品是否存在购物车中
        CartInfo cartInfo = null;
        if (hashOps.hasKey(skuId.toString())) {
            //存在-对购物数量累加,修改更新时间
            cartInfo = hashOps.get(skuId.toString());
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setUpdateTime(new Date());
            //hashOps.put(skuId.toString(), cartInfo);
        } else {
            //不存在构建新CarInfo对象存入Redis
            //远程调用商品微服务 获取商品信息
            SkuInfo skuInfo = productFeignClient.getSkuInfoAndImages(skuId);
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            if (skuInfo != null) {
                cartInfo = new CartInfo();
                cartInfo.setSkuPrice(skuPrice);
                cartInfo.setCartPrice(skuPrice);
                cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
                cartInfo.setSkuId(skuId);
                cartInfo.setSkuName(skuInfo.getSkuName());
                cartInfo.setSkuNum(skuNum);
                cartInfo.setUserId(userId);
                cartInfo.setUpdateTime(new Date());
                cartInfo.setCreateTime(new Date());
            }
        }
        // 无论新增 修改购物车 都需要写会到Redis中
        hashOps.put(skuId.toString(), cartInfo);
    }


    /**
     * 获取用户(登录用户/临时用户)购物车hash结构的Key
     *
     * @param userId
     * @return
     */
    private String getCartKey(String userId) {
        String redisKey = RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
        return redisKey;
    }


    /**
     * 暂时版本:分别查询登录购物车列表 跟 未登录购物车列表
     * 获取用户购物车商品列表(包含购物车合并逻辑)
     *
     * @param userId
     * @param userTempId
     * @return
     */
    //@Override
    //public List<CartInfo> cartList(String userId, String userTempId) {
    //    //1.处理未登录购物车列表
    //    //1.1 声明未登录购物车集合
    //    List<CartInfo> noLoginCartList = null;
    //    if (StringUtils.isNotBlank(userTempId)) {
    //        //1.2 查询未登录购物车列表
    //        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(this.getCartKey(userTempId));
    //        noLoginCartList = hashOps.values();
    //        return noLoginCartList;
    //    }
    //
    //    //2.已登录购物车列表
    //    //2.1 声明已登录购物车集合
    //    List<CartInfo> loginCartList = null;
    //    if (StringUtils.isNotBlank(userId)) {
    //        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(this.getCartKey(userId));
    //        //2.2 查询已登录购物车列表
    //        loginCartList = hashOps.values();
    //        return loginCartList;
    //    }
    //    return null;
    //}


    //public static void main(String[] args) {
    //    CartInfo cartInfo = new CartInfo();
    //    cartInfo.setSkuId(1L);
    //    cartInfo.setSkuName("华为P50");
    //    cartInfo.setCreateTime(new Date());
    //
    //
    //    CartInfo cartInfo1 = new CartInfo();
    //    cartInfo1.setSkuId(2L);
    //    cartInfo1.setSkuName("华为P60");
    //    cartInfo1.setCreateTime(new Date(System.currentTimeMillis() + 50000));
    //
    //
    //    List<CartInfo> cartInfoList = Arrays.asList(cartInfo, cartInfo1);
    //
    //    List<CartInfo> collect = cartInfoList.stream().sorted((o1, o2) -> {
    //        return DateUtil.truncatedCompareTo(o2.getCreateTime(), o1.getCreateTime(), Calendar.MILLISECOND);
    //    }).collect(Collectors.toList());
    //
    //    System.out.println(collect);
    //
    //}


    /**
     * 获取用户购物车商品列表(包含购物车合并逻辑)
     * 不合并购物车情况:
     * 1.用户未登录 直接返回未登录购物车列表
     * 2.用户从未登录变登录状态;未登录购物车数据为空 直接返回已登录购物车数据
     * <p>
     * 合并购物车情况:
     * 用户在未登录情况下添加商品到购物车(未登录购物车有数据);用户进行登录,将未登录购物车中商品跟已登录购物车中商品进行合并.合并后删除未登录购物车数据
     *
     * @param userId
     * @param userTempId
     * @return
     */
    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        //1.如果临时用户ID有值,尝试查询临时用户未登录购物车列表
        List<CartInfo> noLoginCartList = null;
        if (StringUtils.isNotBlank(userTempId)) {
            BoundHashOperations<String, String, CartInfo> noLoginHashOps = redisTemplate.boundHashOps(this.getCartKey(userTempId));
            noLoginCartList = noLoginHashOps.values();
        }

        //如果用户ID为空,不需要合并直接返回未登录购物车数据即可(排序)
        if (StringUtils.isBlank(userId) && !CollectionUtils.isEmpty(noLoginCartList)) {
            noLoginCartList = noLoginCartList.stream().sorted((o1, o2) -> {
                return DateUtil.truncatedCompareTo(o2.getUpdateTime(), o1.getUpdateTime(), Calendar.SECOND);
            }).collect(Collectors.toList());
            return noLoginCartList;
        }

        //2.如果用户ID有值,并且未登录购物车不为空,需要合并
        //2.1 查询已登录购物车列表
        BoundHashOperations<String, String, CartInfo> loginHashOps = redisTemplate.boundHashOps(this.getCartKey(userId));
        List<CartInfo> loginCartList = loginHashOps.values();

        //3.合并购物车操作
        if (!CollectionUtils.isEmpty(noLoginCartList)) {
            //3.1 遍历未登录购物车列表 判断skuId 是否在 用户购物车hash结构中存在
            noLoginCartList.stream().forEach(noLoginCartInfo -> {
                CartInfo loginCartInfo = loginHashOps.get(noLoginCartInfo.getSkuId().toString());
                //3.2 存在商品数量累加
                if (loginCartInfo != null) {
                    loginCartInfo.setSkuNum(loginCartInfo.getSkuNum() + noLoginCartInfo.getSkuNum());
                    loginCartInfo.setUpdateTime(new Date());
                    //得到未登录购物车上选中状态,合并后更新登录购物车选中状态
                    if (noLoginCartInfo.getIsChecked().intValue() == 1) {
                        loginCartInfo.setIsChecked(1);
                    }
                    loginHashOps.put(loginCartInfo.getSkuId().toString(), loginCartInfo);
                } else {
                    //3.3 不存在-新增购物车商品
                    noLoginCartInfo.setUserId(userId);
                    loginHashOps.put(noLoginCartInfo.getSkuId().toString(), noLoginCartInfo);
                }
            });
        }

        //3.合并后删除未登录购物车所有数据
        redisTemplate.delete(this.getCartKey(userTempId));

        //4.再次查询redis中合并后购物车列表,进行排序
        loginCartList = loginHashOps.values();
        if (!CollectionUtils.isEmpty(loginCartList)) {
            loginCartList = loginCartList.stream().sorted((o1, o2) -> {
                return DateUtil.truncatedCompareTo(o2.getUpdateTime(), o1.getUpdateTime(), Calendar.SECOND);
            }).collect(Collectors.toList());
        }
        return loginCartList;
    }

    /**
     * 修改购物车商品选中状态
     *
     * @param userId
     * @param skuId
     * @param isChecked
     * @return
     */
    @Override
    public void updateCheck(String userId, Long skuId, int isChecked) {
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(this.getCartKey(userId));
        Boolean exists = hashOps.hasKey(skuId.toString());
        if (exists) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOps.put(skuId.toString(), cartInfo);
        }
    }


    /**
     * 删除购物车中商品
     *
     * @param skuId
     * @return
     */
    @Override
    public void deleteCart(String userId, Long skuId) {
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(this.getCartKey(userId));
        Boolean exists = hashOps.hasKey(skuId.toString());
        if (exists) {
            hashOps.delete(skuId.toString());
        }
    }

    /**
     * 查询指定用户购物车中选中商品列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        //1.构建用户购物车hash结构redisKey
        String cartKey = getCartKey(userId.toString());
        //2.查询所有购物车商品列表
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        //3.将购物车信息中isChecked=1过滤出来
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList = cartInfoList.stream().filter(cartInfo -> {
                //过滤条件  true:需要数据  false:不需要数据
                return cartInfo.getIsChecked().intValue() == 1;
            }).collect(Collectors.toList());
        }
        return cartInfoList;
    }


    /**
     * 全选 全部取消勾选
     *
     * @param userId
     * @param isChecked
     */
    @Override
    public void allCheckCart(String userId, Integer isChecked) {
        //1.构建用户购物车hash结构redisKey
        String cartKey = getCartKey(userId.toString());
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //2.查询所有购物车商品列表
        List<CartInfo> cartInfoList = hashOps.values();

        //3.修改选中状态
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            for (CartInfo cartInfo : cartInfoList) {
                cartInfo.setIsChecked(isChecked);
                hashOps.put(cartInfo.getSkuId().toString(), cartInfo);
            }
        }
    }


    /**
     * 清理购物车商品
     *
     * @param userId
     */
    @Override
    public void clearCart(String userId) {
        //1.构建用户购物车hash结构redisKey
        String cartKey = getCartKey(userId.toString());
        redisTemplate.delete(cartKey);
    }


}
